package com.elasticsearch.ais.service;

import com.elasticsearch.ais.Factory.EsAsyncFactory;
import com.elasticsearch.ais.Factory.EsFactory;
import com.elasticsearch.ais.annotation.ElasticsearchAsync;
import com.elasticsearch.ais.config.Config;
import com.elasticsearch.ais.config.Scanner;
import com.elasticsearch.ais.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import java.io.InputStream;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

/*
 *@author:lihang
 *@email:631533483@qq.com
 */

@ConditionalOnWebApplication
public class EsAsyncRegistryBean  implements ApplicationContextAware, BeanDefinitionRegistryPostProcessor {
    private ApplicationContext applicationContext;
    private Set<Class<?>> set =new HashSet<>();
    Logger log = LoggerFactory.getLogger(ElasticsearchAsync.class);

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        try {
            this.setSet();
        }
        catch (Exception e){
            log.error("Failed to load bean, please reload or check for errors\n");
            log.error(e.toString());
        }
        if(set.isEmpty()){
            log.info("Interface without dynamic agent\n");
        }
        else {
        for (Class<?> c : set) {
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(c);
            GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
            definition.getPropertyValues().add("interfaceClass", definition.getBeanClassName());
            definition.setBeanClass(EsAsyncFactory.class);
            definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
            // 注册bean名,一般为类名首字母小写
            String name=c.getSimpleName();
            name=name.substring(0,1).toLowerCase()+name.substring(1,name.length());
            beanDefinitionRegistry.registerBeanDefinition(name, definition);
            log.info(c.getSimpleName()+" registry as "+name);
        }
        }
    }
    private void setSet() throws Exception {
        ClassPathResource classPathResource1 = new ClassPathResource("application.yml");
        ClassPathResource classPathResource2 = new ClassPathResource("application.properties");
        ClassPathResource classPathResource3 = new ClassPathResource("bootstap.yml");
        ClassPathResource classPathResource4 = new ClassPathResource("bootstap.properties");
        Properties pros=new Properties();
        String path=null;
        InputStream inputStream;
        if(classPathResource3.exists()){
            inputStream=classPathResource3.getInputStream();
            pros.load(inputStream);
            path=pros.getProperty("aisResource");
            if(StringUtils.isNotBlank(path)){
                set = new Scanner().getAnnotationClasses(path,ElasticsearchAsync.class);
            }
        }
        else if(classPathResource1.exists()){
            inputStream=classPathResource1.getInputStream();
            pros.load(inputStream);
            path=pros.getProperty("aisResource");
            if(StringUtils.isNotBlank(path)){
                set = new Scanner().getAnnotationClasses(path,ElasticsearchAsync.class);
            }
        }
        else if(classPathResource4.exists()){
            inputStream=classPathResource4.getInputStream();
            pros.load(inputStream);
            path=pros.getProperty("elasticsearch.ais.aisResource");
            if(StringUtils.isNotBlank(path)){
                set = new Scanner().getAnnotationClasses(path,ElasticsearchAsync.class);
            }
        }
        else if (classPathResource2.exists()){
            inputStream=classPathResource2.getInputStream();
            pros.load(inputStream);
            path=pros.getProperty("elasticsearch.ais.aisResource");
            if(StringUtils.isNotBlank(path)){
                set = new Scanner().getAnnotationClasses(path,ElasticsearchAsync.class);
            }
        }
        else {
            set = new Scanner().getAnnotationClasses("com",ElasticsearchAsync.class);
        }
    }



}

